#region Copyright (c) 2006-2011 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2011 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion

using System;
using System.Text;
using Widgetsphere.Generator.Models;

namespace Widgetsphere.Generator.DAL.ProjectItemGenerators.ConfigValues
{
	class ConfigValuesExtenderTemplate : DomainProjectTemplate
	{
		private readonly StringBuilder sb = new StringBuilder();

		#region Constructors
		public ConfigValuesExtenderTemplate(ModelRoot model)
		{
			_model = model;
		}
		#endregion

		#region BaseClassTemplate overrides
		public override string FileContent
		{
			get
			{
				GenerateContent();
				return sb.ToString();
			}
		}

		public override string FileName
		{
			get
			{
				return string.Format("ConfigurationValues.cs");
			}
		}
		#endregion

		#region GenerateContent
		private void GenerateContent()
		{
			try
			{
				Widgetsphere.Generator.GenerationHelper.AppendCopyrightInCode(sb, _model);
				this.AppendUsingStatements();
				sb.AppendLine("namespace " + this.GetLocalNamespace() + ".Business");
				sb.AppendLine("{");
				this.AppendClass();
				sb.AppendLine("}");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

		#region namespace / objects
		public void AppendUsingStatements()
		{
			sb.AppendLine("using System;");
			sb.AppendLine("using Widgetsphere.Core.DataAccess;");
			sb.AppendLine("using System.Configuration;");
			sb.AppendLine("using System.Data.SqlClient;");
			sb.AppendLine();
		}

		public void AppendClass()
		{
			sb.AppendLine("	/// <summary>");
			sb.AppendLine("	/// This is a static class used to define the database connection properties");
			sb.AppendLine("	/// </summary>");
			sb.AppendLine("	public partial class ConfigurationValues : Widgetsphere.Core.DataAccess.IConfigurationValues");
			sb.AppendLine("	{");
			sb.AppendLine("		private static ConfigurationValues _instance;");
			sb.AppendLine();
			sb.AppendLine("		private string _connectionString = string.Empty;");
			sb.AppendLine("		private string _dataAccessServiceUrl = string.Empty;");
			sb.AppendLine("		private string _modifier = null;");
			sb.AppendLine("		private int _defaultTimeOut = 30;");
			sb.AppendLine();
			sb.AppendLine("		private ConfigurationValues()");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				var cf = new ConfigurationFile();");
			sb.AppendLine("				if(cf.DirectConnect)");
			sb.AppendLine("					_connectionString = cf.ConfigString;");
			sb.AppendLine("				else");
			sb.AppendLine("					_dataAccessServiceUrl = cf.ConfigString;");
			sb.AppendLine("			}");
			sb.AppendLine("			catch { }");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				_connectionString = ConfigurationManager.ConnectionStrings[\"" + this.GetLocalNamespace() + "\"].ConnectionString;");
			sb.AppendLine("			}");
			sb.AppendLine("			catch { }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Returns a singleton configuration object.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static ConfigurationValues GetInstance()");
			sb.AppendLine("		{");
			sb.AppendLine("			if (_instance == null)");
			sb.AppendLine("				_instance = new ConfigurationValues();");
			sb.AppendLine("			return _instance;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the connection string for all static select methods.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public virtual string ConnectionString");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return _connectionString; }");
			sb.AppendLine("			set { _connectionString = value; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines if the web service is used (remote conection) or this is a direct database connection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		[Obsolete(\"This property no longer applies.\")]");
			sb.AppendLine("		public virtual bool DirectConnect");
			sb.AppendLine("		{");
			sb.AppendLine("			get");
			sb.AppendLine("			{");
			sb.AppendLine("				if (this.DataAccessServiceUrl == string.Empty) return true;");
			sb.AppendLine("				else return false;");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// The URL to the web servive that is used to pass database across the wire.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		[Obsolete(\"This property no longer applies.\")]");
			sb.AppendLine("		public virtual string DataAccessServiceUrl");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return _dataAccessServiceUrl; }");
			sb.AppendLine("			set { _dataAccessServiceUrl = value; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// The modifier that will be used for auditing if none is specified");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public virtual string Modifier");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return _modifier; }");
			sb.AppendLine("			set { _modifier = value; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// The timeout in seconds of the database connection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public virtual int DefaultTimeOut");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return _defaultTimeOut; }");
			sb.AppendLine("			set");
			sb.AppendLine("			{");
			sb.AppendLine("				if (value < 0)");
			sb.AppendLine("					value = 0;");
			sb.AppendLine("				_defaultTimeOut = value;");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		internal static string GetSQLTableMap(string original, string baseColumnSQL, string newAlias, string fieldName)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (!newAlias.Contains(\"[\")) newAlias = \"[\" + newAlias + \"]\";");
			sb.AppendLine("			if (!fieldName.Contains(\"[\")) fieldName = \"[\" + fieldName + \"]\";");
			sb.AppendLine("			return original.Replace(baseColumnSQL, newAlias + \".\" + fieldName + string.Empty);");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the version of the model that created this library.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public virtual string Version");
			sb.AppendLine("		{");
		
			var cacheFile = new Widgetsphere.Generator.Common.ModelCacheFile(_model.GeneratorProject);
			var genVersion = cacheFile.GeneratedVersion;
			sb.AppendLine("			get { return \"" + _model.Version + "." + genVersion + "\"; }");

			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the key of the model that created this library.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public virtual string ModelKey");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return \"" + _model.Key + "\"; }");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines if the API matches the database connection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <returns></returns>");
			sb.AppendLine("		public virtual bool IsValidConnection()");
			sb.AppendLine("		{");
			sb.AppendLine("			return IsValidConnection(true);");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines if the API matches the database connection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"checkVersion\">Determines if the check also includes the exact version of the model</param>");
			sb.AppendLine("		/// <returns></returns>");
			sb.AppendLine("		public virtual bool IsValidConnection(bool checkVersion)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (string.IsNullOrEmpty(this.ConnectionString))");
			sb.AppendLine("				return false;");
			sb.AppendLine();
			sb.AppendLine("			string modelKey = GetDatabaseExtendedProperty(this.ConnectionString, \"ModelKey\");");
			sb.AppendLine("			if (string.Compare(this.ModelKey, modelKey, true) != 0)");
			sb.AppendLine("				return false;");
			sb.AppendLine();
			sb.AppendLine("			if (checkVersion)");
			sb.AppendLine("			{");
			sb.AppendLine("				string dbVersion = GetDatabaseExtendedProperty(this.ConnectionString, \"dbVersion\");");
			sb.AppendLine("				if (dbVersion != this.Version)");
			sb.AppendLine("					return false;");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			return true;");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		private static string GetDatabaseExtendedProperty(string connectionString, string propertyName)");
			sb.AppendLine("		{");
			sb.AppendLine("			string returnVal = string.Empty;");
			sb.AppendLine("			returnVal = SelectExtendedProperty(connectionString, propertyName, string.Empty, string.Empty, string.Empty);");
			sb.AppendLine("			return returnVal;");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		private static string SelectExtendedProperty(string connectionString, string property, string user, string table, string column)");
			sb.AppendLine("		{");
			sb.AppendLine("			string returnVal = string.Empty;");
			sb.AppendLine("			string userName = string.Empty;");
			sb.AppendLine("			string userValue = string.Empty;");
			sb.AppendLine("			string tableName = string.Empty;");
			sb.AppendLine("			string tableValue = string.Empty;");
			sb.AppendLine("			string columnName = string.Empty;");
			sb.AppendLine("			string columnValue = string.Empty;");
			sb.AppendLine();
			sb.AppendLine("			property = \"'\" + property + \"'\";");
			sb.AppendLine("			if (user == string.Empty)");
			sb.AppendLine("			{");
			sb.AppendLine("				userName = \"NULL\";");
			sb.AppendLine("				userValue = \"NULL\";");
			sb.AppendLine("			}");
			sb.AppendLine("			else");
			sb.AppendLine("			{");
			sb.AppendLine("				userName = \"'user'\";");
			sb.AppendLine("				userValue = \"'\" + user + \"'\";");
			sb.AppendLine("			}");
			sb.AppendLine("			if (table == string.Empty)");
			sb.AppendLine("			{");
			sb.AppendLine("				tableName = \"NULL\";");
			sb.AppendLine("				tableValue = \"NULL\";");
			sb.AppendLine("			}");
			sb.AppendLine("			else");
			sb.AppendLine("			{");
			sb.AppendLine("				tableName = \"'table'\";");
			sb.AppendLine("				tableValue = \"'\" + table + \"'\";");
			sb.AppendLine("			}");
			sb.AppendLine("			if (column == string.Empty)");
			sb.AppendLine("			{");
			sb.AppendLine("				columnName = \"NULL\";");
			sb.AppendLine("				columnValue = \"NULL\";");
			sb.AppendLine("			}");
			sb.AppendLine("			else");
			sb.AppendLine("			{");
			sb.AppendLine("				columnName = \"'column'\";");
			sb.AppendLine("				columnValue = \"'\" + column + \"'\";");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();");
			sb.AppendLine("			System.Data.SqlClient.SqlDataReader externalReader = null;");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				conn.ConnectionString = connectionString;");
			sb.AppendLine("				conn.Open();");
			sb.AppendLine("				SqlCommand cmdGetExtProp = new SqlCommand();");
			sb.AppendLine("				cmdGetExtProp.CommandText = String.Format(\"SELECT value FROM ::fn_listextendedproperty({0}, {1}, {2}, {3}, {4}, {5}, {6})\", new object[] { property, userName, userValue, tableName, tableValue, columnName, columnValue });");
			sb.AppendLine("				cmdGetExtProp.CommandType = System.Data.CommandType.Text;");
			sb.AppendLine("				cmdGetExtProp.Connection = conn;");
			sb.AppendLine("				externalReader = cmdGetExtProp.ExecuteReader();");
			sb.AppendLine("				if (externalReader.Read())");
			sb.AppendLine("				{");
			sb.AppendLine("					if (externalReader[0] != System.DBNull.Value)");
			sb.AppendLine("					{");
			sb.AppendLine("						returnVal = externalReader.GetString(0);");
			sb.AppendLine("					}");
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine("			catch (Exception ex)");
			sb.AppendLine("			{");
			sb.AppendLine("				throw ex;");
			sb.AppendLine("			}");
			sb.AppendLine("			finally");
			sb.AppendLine("			{");
			sb.AppendLine("				if (externalReader != null)");
			sb.AppendLine("					externalReader.Close();");
			sb.AppendLine("				if (conn != null)");
			sb.AppendLine("					conn.Close();");
			sb.AppendLine("			}");
			sb.AppendLine("			return returnVal;");
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("	}");
		}
		#endregion

		#region append regions
		#endregion

		#region append member variables
		#endregion

		#region append constructors
		#endregion

		#region append properties
		#endregion

		#region append methods
		#endregion

		#region append operator overloads
		#endregion

	}
}